package com.sakiko.aspects;

// todo: aop_04 通知内获取目标方法的详细信息

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/*
    todo: 通知方法中获取目标方法的信息！ 一般用于日志功能做详细的记录
        1、所有通知(前置，返回，异常，后置)都可以获取目标方法信息
            通知方法 (JoinPoint joinPoint)
                joinPoint.getTarget() -> 获取目标对象
                joinPoint.getSignature() -> 获取目标方法
                joinPoint.getArgs() -> 获取调用方法传递的参数
        2、返回通知可以额外获取目标方法的返回结果
            2.1 返回通知 (Object 形参名)
            2.2 @AfterReturning(value = "com.sakiko.pointcuts.MyPointcut.pointcut04()", returning = "形参名")
        3、异常通知可以获取异常信息对象
            3.1 异常通知 (Throwable 形参名)
            3.2 @AfterThrowing(value = "com.sakiko.pointcuts.MyPointcut.pointcut04()", throwing = "形参名")
 */

// todo: aop_04
@Aspect
@Component
public class LogAspect02 {

    @Before("com.sakiko.pointcuts.MyPointcut.pointcut04()")
    public void before(JoinPoint joinPoint) {

        // 包名.类名
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();

        // 获取方法
        Signature signature = joinPoint.getSignature();
        // 获取方法名
        String methodName = signature.getName();

        // 获取参数
        Object[] args = joinPoint.getArgs();

        System.out.println("【" + simpleName + "】: " + methodName + " 老弟来了..." + " 参数: " + Arrays.toString(args));
    }

    @AfterReturning(value = "com.sakiko.pointcuts.MyPointcut.pointcut04()", returning = "res")
    public void afterReturning(JoinPoint joinPoint, Object res) {
        // 类名
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        System.out.println("【" + simpleName + "】: " + methodName + " 老弟 bye bye..." + "结果为: [" + res + "]");
    }

    @AfterThrowing(value = "com.sakiko.pointcuts.MyPointcut.pointcut04()", throwing = "exc")
    public void afterThrowing(JoinPoint joinPoint, Throwable exc) {
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        System.out.println("【" + simpleName + "】: " + methodName + " 老弟不行了 throw exc: " + exc.getMessage());
    }

}
